package cn.dlc.com.linear;

import lombok.Data;

/**
 * @author 邓立川
 * @date 2021/3/21 12:08
 * @desc 当前类的描述信息
 */
public class JosePh {

    @Data
    private static class Node<T> {
        // 节点存储的数据
        private T item;

        // 下一个元素
        private Node<T> next;

        public Node(T item, Node next) {
            this.item = item;
            this.next = next;
        }
    }

    public static void main(String[] args) {
        Node<Integer> circleNodes = createCircleNodes(2);

        System.out.println(circleNodes.getItem());
        System.out.println(circleNodes.getNext().getItem());
        System.out.println(circleNodes.getNext().getNext().getItem());

        System.out.println("构建列表完成。。。。");
        Node<Integer> result = deleteNode(circleNodes);

        Node<Integer> temp = result;
        System.out.println(temp.getItem());
        System.out.println(temp.getNext().getItem());
        System.out.println(temp.next.next.getItem());

    }

    // 构建循环链表，返回第一个节点
    public static Node<Integer> createCircleNodes(int i){
        // 第一个节点
        Node<Integer> first = null;
        // 前一个节点
        Node<Integer> pre = null;

        for (int j = 1; j <= i; j++) {
            // 如果是第一个节点
            if(j == 1) {
                first = new Node<>(j,null);
                pre = first;
                // 重新开始循环
                continue;
            }

            // 如果不是第一个节点
            Node<Integer> newNode = new Node<>(j, null);
            // 设置为上一个节点的下一个节点
            pre.setNext(newNode);
            // 重置上一个节点，将当前节点作为上一个节点
            pre = newNode;

            if(j == i) {
                // 最后一个几点，将其next指向first
                pre.setNext(first);
            }
        }

        return first;
    }

    // 删除节点
    public static Node<Integer> deleteNode(Node<Integer> first){
        // 计数器定义一个
        int count = 0;
        Node<Integer> n = first;
        // 记录当前节点的上一个节点
        Node<Integer> before = null;

        // 如果n.next = n那么表示剩余一个元素了
        while(n != n.next) {

            // 模拟报数
            count++;
            if(count == 3) {
                // 删除当前元素，并且将当前元素的前一个元素指向当前元素的下一个元素
                before.setNext(n.getNext());
                System.out.println("删除的元素是" + n.getItem());
                // 重置报数
                count = 0;
                // 继续下面的元素
                n = n.next;
            } else {
                // 不是3的话,元素后移，记录上一个节点
                before = n;
                n = n.next;
            }
        }

        // 打印的是最后一个元素
        System.out.println(n.getItem());

        // 返回处理之后的首节点
        return n;
    }

}
